package com.bjpowernode.boss.mvc.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bjpowernode.boss.common.client.RedisClient;
import com.bjpowernode.boss.common.consants.KeyConst;
import com.bjpowernode.boss.common.enums.ResponseCode;
import com.bjpowernode.boss.common.exception.BossException;
import com.bjpowernode.boss.common.utils.JwtUtils;
import com.bjpowernode.boss.dao.entity.PmsMenu;
import com.bjpowernode.boss.dao.entity.PmsOperator;
import com.bjpowernode.boss.dao.mapper.PmsMenuMapper;
import com.bjpowernode.boss.dao.mapper.PmsOperatorMapper;
import com.bjpowernode.boss.mvc.models.dto.operator.LoginResponseDto;
import com.bjpowernode.boss.mvc.models.form.operator.LoginForm;
import com.bjpowernode.boss.mvc.models.menus.MenuItem;
import com.bjpowernode.boss.mvc.models.menus.SubMenu;
import com.bjpowernode.boss.mvc.service.OperatorService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author Mrs.cui
 * 2024-07-07-22-12
 */
@Service
public class OperatorServiceImpl implements OperatorService {

    @Resource
    private RedisClient redisClient;

    @Resource
    private PmsOperatorMapper operatorMapper;

    @Resource
    private PmsMenuMapper menuMapper;

    @Override
    public LoginResponseDto operatorLogin(LoginForm loginForm) {
        //pms_operator表中login_name字段值是唯一的
        QueryWrapper<PmsOperator> wrapper = new QueryWrapper<>();
        wrapper.eq("login_name", loginForm.getLoginName());
        PmsOperator pmsOperator = operatorMapper.selectOne(wrapper);
        if (pmsOperator == null) {
            throw new BossException(ResponseCode.OPERATOR_LOGIN_NAME_PWD);
        }
        //获取盐值salt,进行密码比对
        String salt = pmsOperator.getSalt();

        //进行密码的生成规则，把登录的密码和salt重新计算得到一个新密码和数据库存储的密码对比
        String requestLoginPwd = DigestUtil.md5Hex(loginForm.getLoginPwd() + salt);
        if (!requestLoginPwd.equals(pmsOperator.getLoginPwd())) {
            throw new BossException(ResponseCode.OPERATOR_LOGIN_NAME_PWD_1);
        }

        //登录名称和密码正确，生成jwt
        String jwt = JwtUtils.createJWT(UUID.randomUUID().toString(), 120);

        //存储jwt到redis
        Map<String, String> redisData = new HashMap<>();
        redisData.put("jwt", jwt);
        redisData.put("operatorId", String.valueOf(pmsOperator.getId()));
        redisData.put("loginTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        String loginKey = KeyConst.TOKEN_OPERATOR + pmsOperator.getId();
        Boolean saveToken = redisClient.setHashMap(loginKey, redisData, 120, TimeUnit.MINUTES);
        if (!saveToken) {
            throw new BossException(ResponseCode.OPERATOR_SAVE_TOKEN);
        }

        //登录成功， jwt成功。返回登录结果给前端
        return new LoginResponseDto(pmsOperator.getId(), pmsOperator.getShowName(), jwt);
    }

    @Override
    public List<SubMenu> getMenuByLoginUser(Long operatorId) {
        //从数据库查询菜单数据
        List<PmsMenu> pmsMenuList = menuMapper.selectListByUserId(operatorId);

        //Map<String,List<PmsMenu>> key是number列的前4位， value:number是前4位相同的List
        String numberPrefix4 ="";
        HashMap<String,List<PmsMenu>> listMapMenu = new HashMap<>();
        for (PmsMenu pmsMenu : pmsMenuList) {
            numberPrefix4 = pmsMenu.getNumber().substring(0, 4);
            if (listMapMenu.containsKey(numberPrefix4)){
                //有numberPrefix4的key,获取value，添加PmsMenu到List集合
                listMapMenu.get(numberPrefix4).add(pmsMenu);
            }else {
                //没有numberPrefix4 的key
                ArrayList<PmsMenu> itemList = new ArrayList<>();
                itemList.add(pmsMenu);
                listMapMenu.put(numberPrefix4, itemList);
            }
        }
        //从Map中查询菜单，对List计划进行组装，得到List<SubMenu>
        ArrayList<SubMenu> subMenuList = new ArrayList<>();
        listMapMenu.forEach((number,menuList) ->{
            String leaf ="";
            SubMenu subMenu = new SubMenu();
            List<MenuItem> items = new ArrayList<>();

            for (PmsMenu pmsMenu : menuList) {
                leaf = pmsMenu.getIsLeaf();
                if ("NO".equals(leaf)){
                    subMenu.setName(pmsMenu.getName());
                    subMenu.setUrl(pmsMenu.getUrl());
                    subMenu.setNumber(pmsMenu.getNumber());
                }else {
                    MenuItem item = new MenuItem();
                    item.setName(pmsMenu.getName());
                    item.setUrl(pmsMenu.getUrl());
                    item.setNumber(pmsMenu.getNumber());
                    items.add(item);
                }
            }
            //给SubMenu的item赋值
            subMenu.setItems(items);
            subMenuList.add(subMenu);
        });
        return subMenuList.stream().sorted(Comparator.comparing(SubMenu::getNumber)).toList();
    }
}
